package com.example.usagelock;

import android.graphics.*;

public class CircleEquation {
        PointF _center;
        int _radius;
        
        public CircleEquation(PointF center, int radius)
        {
                _center = center;
                _radius = radius;
        }
        
        public CircleEquation(float x, float y, int radius)
        {
                _center = new PointF(x, y);
                _radius = radius;
        }
        
        private float[] CalculateX(float initialX, int count)
        {
                float fractionDegree = (float)((2 * Math.PI) / count);
                float initialDegree = - (float)Math.PI;
                float[] result = new float[count];
                result[0] = initialX;
                
                float tempDegree = 0.0f;
                for(int i = 1; i < count; i++)
                {
                        tempDegree = initialDegree - fractionDegree * i;
                        result[i] = _center.x + _radius * (float)Math.cos(tempDegree);
                }
                
                return result;
        }
        
        private float[] CalculateEquation(float x)
        {
                // Circle Equation
                // x^2 + y^2 = r^2
                //(x-cx)^2 + (y-cy)^2 = r^2 : cx, cy = center
                
                // A + B = C
                double cSide = Math.pow(_radius, 2.0);
                double aSide = Math.pow((x - _center.x), 2.0);
                
                double bSide = Math.sqrt(cSide-aSide);
                
                float[] result = new float[2]; 
                
                result[0] = (float)(-bSide + _center.y);
                result[1] = (float)(bSide + _center.y);
                
                return result;
        }
        
        public void SetCenter(PointF center)
        {
                _center = center;
        }
        
        public void SetCenter(float x, float y)
        {
                _center = new PointF(x, y);
        }
        
        public void SetRadius(int radius)
        {
                _radius = radius;
        }
        
        /**
         * Get points at Circle Equation.
         * @param pointCount : Integer( 2*(x + 1) )
         * @return Points at Circle Equation.
         * If pointCount was Odd number, return null.
         * Points start most left point and Clock wise;
         */
        public PointF[] GetPoints(int pointCount)
        {
                if(pointCount % 2 != 0)
                        return null;
                
                // Initialize Result Point
                PointF[] resultPoint = new PointF[pointCount];
                for(int i = 0; i < pointCount; i++)
                        resultPoint[i] = new PointF();
                
                // Calculate Fraction
                int fraction = (int)Math.ceil((_radius * 2) / ((pointCount-2)/2 + 1));
                // Initialize X value of Result Point
                resultPoint[0].x = _center.x - _radius;
                
                // Calculate X value of Points
                float[] x = CalculateX(resultPoint[0].x, pointCount);
                for(int i = 1; i < pointCount; i++)
                {
                        resultPoint[i].x = x[i];
                }
                
                // Circle Equation
                // x^2 + y^2 = r^2
                //(x-cx)^2 + (y-cy)^2 = r^2 : cx, cy = center
                for(int i = 0; i < pointCount; i++)
                {
                        if(i <= pointCount/2)
                                resultPoint[i].y = CalculateEquation(resultPoint[i].x)[0];
                        else
                                resultPoint[i].y = CalculateEquation(resultPoint[i].x)[1];
                }
                
                return resultPoint;
        }
        
        public Rect[] GetRects(int rectCount, int rectWidth)
        {
                PointF[] centers = GetPoints(rectCount);
                Rect[] rects = new Rect[rectCount];
                
                // initialize rects
                for(int i = 0; i < rectCount; i++){
                        rects[i] = new Rect();
                }
                
                // calculate rects
                int left = 0;
                int top = 0;
                for(int i = 0; i < rectCount; i++){
                        left = (int)(centers[i].x - rectWidth/2);
                        top = (int)(centers[i].y - rectWidth/2);
                        rects[i].set(left, top, left+rectWidth, top+rectWidth);
                }
                
                return rects;
        }
}